package com.panda.utils;

import com.panda.pojo.Component;
import com.panda.pojo.Context;
import com.panda.pojo.Scope;

import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

//处理变量
class ParamUtils {

    /*
        scope是一个关键字,区别于var

        global 也是一个关键字 声明全局变量


        私有域变量:对于组件而言,无法从外部映射只能该组件内及其子作用域私有的变量

     */


    private static Pattern pp1 = Pattern.compile("(private[ \n]+)?scope[\n ]+([a-zA-Z_][a-zA-Z0-9_]*)[\n ]*(=)?[\n ]*;?");
    private static Pattern pp2 = Pattern.compile("global[\n ]+([a-zA-Z_][a-zA-Z0-9_]*)[\n ]*(=)?[\n ]*;?");

    static String extractParam(Context context, Scope scope, String s) {

        if ("".equals(s)) {
            return s;
        }

        s = extract1(scope, s);
        s = extract2(context, s);

        return s;

    }

    private static String extract1(Scope scope, String s) {

        Matcher matcher = pp1.matcher(s);

        Set<String> canMappingScopeParams = null;

        if (scope.getElement() instanceof Component) {
            canMappingScopeParams = ((Component) scope.getElement()).getCanMappingScopeParams();
        }

        while (matcher.find()) {

            //变量的声明
            String statement = matcher.group(2).trim();


            //添加变量
            scope.addParam(statement);

            //如果没有赋值行为也要给其添加空的赋值,以此来防止误用父作用域中的域变量
            if (matcher.group(3) == null) {

                //添加一个空的声明防止对父作用域的侵入
                s = s.replace(matcher.group(), statement + " = null;\n");

            }

            if (canMappingScopeParams != null) {


                //如果是非私有的则可以向外部映射
                if (matcher.group(1) == null) {
                    canMappingScopeParams.add(statement);
                }
            }

        }

        s = s.replaceAll(" *scope *", "");

        //私有变量是针对组件定义而言的,非组件定义中不支持private关键字
        if (canMappingScopeParams != null) {
            s = s.replaceAll(" *private *", "");
        }

        return s;
    }

    private static String extract2(Context context, String s) {

        Set<String> globalParam = context.getGlobalParams();

        //全局变量
        Matcher matcher = pp2.matcher(s);

        while (matcher.find()) {

            String statement = matcher.group(1).trim();

            globalParam.add(statement);

        }

        s = s.replaceAll(" *global *", "").replaceAll("\n+;", ";");

        return s;
    }

    static String transform(Context context, Scope scope, String s) {

        if (s.equals("")) {
            return s;
        }

        // s = s.replaceAll("\n*\\.\n*", ".");

        Map<String, Integer> params = scope.getAllParams();

        for (String param : params.keySet()) {

            String sp = "__RDS_CHAR_DOLLARscope___HIDE__POINT___";

            Integer integer = params.get(param);

            for (int i = 0; i < integer; i++) {
                sp += "__RDS_CHAR_DOLLARparent___HIDE__POINT___";
            }

            /*
                前面是点的也被替换
             */

            s = s.replaceAll("((?<=([+\\-/*=%!({\\[><&|^;:\n])|^|(in)) *)" + param + "((?= *[+-/*=%!()}\\[><?&|^.\n])|$)", " " + sp + param);

            s = s.replaceAll("\\?[ \n]*" + param + "[ \n]*:", "?" + sp + param + ":");
            s = s.replaceAll("\\?[ \n]*" + param + "[ \n]*.", "?" + sp + param + ".");

        }

        Set<String> globalParams = context.getGlobalParams();

        //替换全局变量
        for (String param : globalParams) {
            String sp = "__RDS_CHAR_DOLLARrootScope___HIDE__POINT___";
            s = s.replaceAll("((?<=([+\\-/*=%!({\\[><&|^;:\n])|^|(in)) *)" + param + "((?= *[+-/*=%!()}\\[><?&|^.\n])|$)", " " + sp + param);
            s = s.replaceAll("\\?[ \n]*" + param + "[ \n]*:", "?" + sp + param + ":");
            s = s.replaceAll("\\?[ \n]*" + param + "[ \n]*.", "?" + sp + param + ".");

        }

        return s.replace("__RDS_CHAR_DOLLAR", "$").replace("___HIDE__POINT___", ".");

    }


}
